home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 051-075 / scopedisk75 / ispell / src / good.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  8KB  |  512 lines

  1. /* -*- Mode:Text -*- */
  2. /*
  3.  * good.c - see if a word or its root word
  4.  * is in the dictionary.
  5.  *
  6.  * Pace Willisson, 1983
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <ctype.h>
  11. #include "ispell.h"
  12.  
  13. struct dent *lookup();
  14.  
  15. static int wordok;
  16.  
  17.  
  18. good (w)
  19. register char *w;
  20. {
  21.     char nword[100];
  22.     register char *p, *q;
  23.     register n;
  24.  
  25.     for (p = w, q = nword; *p; p++, q++) {
  26.         if (islower (*p))
  27.             *q = toupper (*p);
  28.         else
  29.             *q = *p;
  30.     }
  31.     *q = 0;
  32.  
  33.     rootword[0] = 0;
  34.  
  35.     if (lookup (nword, strlen (nword)) != NULL) {
  36.         return (1);
  37.     }
  38.  
  39.     /* try stripping off suffixes */
  40.  
  41.     n = strlen (w);
  42.     if (n == 1)
  43.         return (1);
  44.  
  45.     if (n < 4)
  46.         return (treelookup (w));
  47.  
  48.     wordok = 0;
  49.  
  50.     /* this part from 'check.mid' */
  51.     switch (nword [ strlen (nword) - 1 ]) {
  52.     case 'D': d_ending (nword); break;    /* FOR "CREATED", "IMPLIED", "CROSSED" */
  53.     case 'T': t_ending (nword); break;    /* FOR "LATEST", "DIRTIEST", "BOLDEST" */
  54.     case 'R': r_ending (nword); break;    /* FOR "LATER", "DIRTIER", "BOLDER" */
  55.     case 'G': g_ending (nword); break;    /* FOR "CREATING", "FIXING" */
  56.     case 'H': h_ending (nword); break;    /* FOR "HUNDREDTH", "TWENTIETH" */
  57.     case 'S': s_ending (nword); break;    /* FOR ALL SORTS OF THINGS ENDING IN "S" */
  58.     case 'N': n_ending (nword); break;    /* "TIGHTEN", "CREATION", "MULIPLICATION" */
  59.     case 'E': e_ending (nword); break;    /* FOR "CREATIVE", "PREVENTIVE" */
  60.     case 'Y': y_ending (nword); break;    /* FOR "QUICKLY" */
  61.     default:
  62.         break;
  63.     }
  64.     
  65.     if (wordok) {
  66.         strcpy (rootword, &hashstrings [ (int)(lastdent->word) ]);
  67.     } else {
  68.         wordok = treelookup (w); /* rootword shouldn't be set in this case */
  69.     }
  70.     return (wordok);
  71.  
  72. }
  73.  
  74.  
  75. g_ending (w)
  76. char *w;
  77. {
  78.     char *p;
  79.     struct dent *dent;
  80.  
  81.     p = w + strlen (w) - 3;    /* if the word ends in 'ing', then *p == 'i' */
  82.     
  83.     if (strcmp (p, "ING") != 0)
  84.         return;
  85.  
  86.     *p = 'E';    /* change I to E, like in CREATING */
  87.     *(p+1) = 0;
  88.  
  89.     if (strlen (w) < 2)
  90.         return;
  91.  
  92.     if ((dent = lookup (w, strlen (w))) != NULL) {
  93.         if (dent->g_flag) 
  94.             wordok = 1;
  95.         return;
  96.     }
  97.  
  98.  
  99.     *p = 0;
  100.  
  101.     if (strlen (w) < 2)
  102.         return;
  103.  
  104.     if (p[-1] == 'E')
  105.         return;    /* this stops CREATEING */
  106.  
  107.     if (strlen (w) < 2)
  108.         return;
  109.  
  110.     if ((dent = lookup (w, strlen (w))) != NULL) {
  111.         if (dent->g_flag)
  112.             wordok = 1;
  113.         return;
  114.     }
  115.     return;
  116. }
  117.  
  118. d_ending (w)
  119. char *w;
  120. {
  121.     char *p;
  122.     struct dent *dent;
  123.  
  124.     p = w + strlen (w) - 2;
  125.  
  126.     if (strcmp (p, "ED") != 0)
  127.         return;
  128.  
  129.     p[1] = 0;    /* kill 'D' */
  130.  
  131.     if ((dent = lookup (w, strlen (w))) != NULL) {    /* like CREATED */
  132.         if (dent->d_flag)
  133.             wordok = 1;
  134.         return;
  135.     }
  136.  
  137.     if (strlen (w) < 3)
  138.         return;
  139.  
  140.     p[0] = 0;
  141.     p--;
  142.  
  143.     /* ED is now completely gone */
  144.  
  145.     if (p[0] == 'I' && !vowel (p[-1])) {
  146.         p[0] = 'Y';
  147.         if ((dent = lookup (w, strlen (w))) != NULL) {
  148.             if (dent->d_flag)
  149.                 wordok = 1;
  150.             return;
  151.         }
  152.     }
  153.  
  154.     if ((p[0] != 'E' && p[0] != 'Y') ||
  155.         (p[0] == 'Y' && vowel (p[-1]))) {
  156.         if ((dent = lookup (w, strlen (w))) != NULL) {
  157.             if (dent->d_flag)
  158.                 wordok = 1;
  159.             return;
  160.         }
  161.     }
  162. }
  163.  
  164. t_ending (w)
  165. char *w;
  166. {
  167.  
  168.     char *p;
  169.     struct dent *dent;
  170.  
  171.     p = w + strlen (w) - 3;
  172.  
  173.     if (strcmp (p, "EST") != 0)
  174.         return;
  175.  
  176.     p[1] = 0;    /* kill 'S' */
  177.  
  178.     if ((dent = lookup (w, strlen (w))) != NULL) {
  179.         if (dent->t_flag)
  180.             wordok = 1;
  181.         return;
  182.     }
  183.  
  184.     if (strlen (w) < 3)
  185.         return;
  186.  
  187.     p[0] = 0;
  188.     p--;
  189.  
  190.     /* EST is now completely gone */
  191.  
  192.     if (p[0] == 'I' && !vowel (p[-1])) {
  193.         p[0] = 'Y';
  194.         if ((dent = lookup (w, strlen (w))) != NULL) {
  195.             if (dent->t_flag)
  196.                 wordok = 1;
  197.             return;
  198.         }
  199.     }
  200.  
  201.     if ((p[0] != 'E' && p[0] != 'Y') ||
  202.         (p[0] == 'Y' && vowel (p[-1]))) {
  203.         if ((dent = lookup (w, strlen (w))) != NULL) {
  204.             if (dent->t_flag)
  205.                 wordok = 1;
  206.             return;
  207.         }
  208.     }
  209.  
  210. }
  211.  
  212.  
  213. r_ending (w)
  214. char *w;
  215. {
  216.     char *p;
  217.     struct dent *dent;
  218.  
  219.     p = w + strlen (w) - 2;
  220.  
  221.     if (strcmp (p, "ER") != 0)
  222.         return;
  223.  
  224.     p[1] = 0;    /* kill 'R' */
  225.  
  226.     if ((dent = lookup (w, strlen (w))) != NULL) {
  227.         if (dent->r_flag)
  228.             wordok = 1;
  229.         return;
  230.     }
  231.  
  232.     if (strlen (w) < 3)
  233.         return;
  234.  
  235.     p[0] = 0;
  236.     p--;
  237.  
  238.     /* ER is now completely gone */
  239.  
  240.     if (p[0] == 'I' && !vowel (p[-1])) {
  241.         p[0] = 'Y';
  242.         if ((dent = lookup (w, strlen (w))) != NULL) {
  243.             if (dent->r_flag)
  244.                 wordok = 1;
  245.             return;
  246.         }
  247.     }
  248.  
  249.     if ((p[0] != 'E' && p[0] != 'Y') ||
  250.         (p[0] == 'Y' && vowel (p[-1]))) {
  251.         if ((dent = lookup (w, strlen (w))) != NULL) {
  252.             if (dent->r_flag)
  253.                 wordok = 1;
  254.             return;
  255.         }
  256.     }
  257.  
  258. }
  259.  
  260. h_ending (w)
  261. char *w;
  262. {
  263.     char *p;
  264.     struct dent *dent;
  265.  
  266.     p = w + strlen (w) - 2;
  267.  
  268.     if (strcmp (p, "TH") != 0)
  269.         return;
  270.  
  271.     *p = 0;
  272.  
  273.     p -= 2;
  274.  
  275.     if (strcmp (p, "IE") == 0) {
  276.         p[0] = 'Y';
  277.         p[1] = 0;
  278.     }
  279.  
  280.     if ((dent = lookup (w, strlen (w))) != NULL)
  281.         if (dent->h_flag)
  282.             wordok = 1;
  283.  
  284. }
  285.  
  286. /*
  287.  * check for flags: X, J, Z, S, P, M
  288.  *
  289.  * X    -ions or -ications or -ens
  290.  * J    -ings
  291.  * Z    -ers or -iers
  292.  * S    -ies or -es or -s
  293.  * P    -iness or -ness
  294.  * M    -'S
  295.  */
  296.  
  297. s_ending (w)
  298. char *w;
  299. {
  300.     char *p;
  301.     struct dent *dent;
  302.  
  303.     p = w + strlen (w);
  304.  
  305.     p[-1] = 0;
  306.  
  307.     if (index ("SXZHY", p[-2]) == NULL || (p[-2] == 'Y'  && vowel (p[-3]))) {
  308.         if ((dent = lookup (w, strlen (w))) != NULL) {
  309.             if (dent->s_flag)
  310.                 wordok = 1;
  311.             return;
  312.         }
  313.     }
  314.  
  315.  
  316.     switch (p[-2]) {    /* letter before S */
  317.     case 'N':    /* X */
  318.         if (strcmp (p-4, "ION") == 0) {
  319.             p[-4] = 'E';
  320.             p[-3] = 0;
  321.             if ((dent = lookup (w, strlen (w))) != NULL) {
  322.                 if (dent->x_flag)
  323.                     wordok = 1;
  324.                 return;
  325.             }
  326.         }
  327.         if (strcmp (p-8, "ICATE") == 0) {
  328.             p[-8] = 'Y';
  329.             p[-7] = 0;
  330.             if ((dent = lookup (w, strlen (w))) != NULL && dent->x_flag)
  331.                 wordok = 1;
  332.             return;
  333.         }
  334.         if (strcmp (p-3, "EN") == 0 && p[-4] != 'E' && p[-4] != 'Y') {
  335.             p[-3] = 0;
  336.             if ((dent = lookup (w, strlen (w))) != NULL && dent->x_flag)
  337.                 wordok = 1;
  338.             return;
  339.         }
  340.     case 'G':    /* J */
  341.         if (strcmp (p-4, "ING") != 0)
  342.             return;
  343.         p[-4] = 'E';
  344.         p[-3] = 0;
  345.         if ((dent = lookup (w, strlen (w))) != NULL) {
  346.             if (dent->j_flag)
  347.                 wordok = 1;
  348.             return;
  349.         }
  350.         p[-4] = 0;
  351.         if (p[-5] == 'E')
  352.             return;
  353.         if ((dent = lookup (w, strlen (w))) != NULL && dent->j_flag)
  354.             wordok = 1;
  355.         return;
  356.     case 'R':    /* Z */
  357.         if (strcmp (p-3, "ER") != 0)
  358.             return;
  359.  
  360.         p[-2] = 0;
  361.         if ((dent = lookup (w, strlen (w))) != NULL) {
  362.             if (dent->z_flag)
  363.                 wordok = 1;
  364.             return;
  365.         }
  366.         if (p[-4] == 'I') {
  367.             p[-4] = 'Y';
  368.             p[-3] = 0;
  369.             if ((dent = lookup (w, strlen (w))) != NULL && dent->z_flag)
  370.                 wordok = 1;
  371.             return;
  372.         }
  373.         p[-3] = 0;
  374.         if ((dent = lookup (w, strlen (w))) != NULL && dent->z_flag)
  375.             wordok = 1;
  376.         return;
  377.     case 'E': /* S (except simple adding of an S) */
  378.         p[-2] = 0;    /* drop the ES */
  379.         if ((dent = lookup (w, strlen (w))) != NULL) {
  380.             if (dent->s_flag)
  381.                 wordok = 1;;
  382.             return;
  383.         }
  384.         if (p[-3] == 'I') {
  385.             p[-3] = 'Y';
  386.             if ((dent = lookup (w, strlen (w))) != NULL && dent->s_flag)
  387.                 wordok = 1;
  388.             return;
  389.         }
  390.         return;
  391.  
  392.     case 'S':    /* P */
  393.         if (strcmp (p-4, "NES") != 0)
  394.             return;
  395.  
  396.         p[-4] = 0;    /* kill 'N' */
  397.         if (p[-5] != 'Y' || vowel (p[-6])) {
  398.             if ((dent = lookup (w, strlen (w))) != NULL) {
  399.                 if (dent->p_flag)
  400.                     wordok = 1;
  401.                 return;
  402.             }
  403.         }
  404.         if (p[-5] == 'I') {
  405.             p[-5] = 'Y';
  406.             if ((dent = lookup (w, strlen (w))) != NULL && dent->p_flag)
  407.                 wordok = 1;
  408.             return;
  409.         }
  410.         return;
  411.     case '\'':    /* M */
  412.         wordok = 1;
  413.         return;
  414.     }
  415. }
  416.  
  417. /* only the N flag */
  418. n_ending (w)
  419. char *w;
  420. {
  421.     char *p;
  422.     struct dent *dent;
  423.  
  424.     p = w + strlen (w);
  425.  
  426.     if (p[-2] == 'E') {
  427.         if (p[-3] == 'E' || p[-3] == 'Y')
  428.             return;
  429.         p[-2] = 0;
  430.         if ((dent = lookup (w, strlen (w))) != NULL && dent->n_flag)
  431.             wordok = 1;
  432.         return;
  433.     }
  434.  
  435.     if (strcmp (p-3, "ION") != 0)
  436.         return;
  437.  
  438.     p[-3] = 'E';
  439.     p[-2] = 0;
  440.  
  441.     if ((dent = lookup (w, strlen (w))) != NULL) {
  442.         if (dent->n_flag)
  443.             wordok = 1;
  444.         return;
  445.     }
  446.  
  447.     if (strcmp (p-7, "ICATE") != 0)    /* check is really against "ICATION" */
  448.         return;
  449.  
  450.     p[-7] = 'Y';
  451.     p[-6] = 0;
  452.     
  453.     if ((dent = lookup (w, strlen (w))) != NULL && dent->n_flag)
  454.         wordok = 1;
  455.     return;
  456. }
  457.  
  458. /* flags: v */
  459. e_ending (w)
  460. char *w;
  461. {
  462.     char *p;
  463.     struct dent *dent;
  464.  
  465.     p = w + strlen (w);
  466.  
  467.     if (strcmp (p-3, "IVE") != 0)
  468.         return;
  469.     p[-3] = 'E';
  470.     p[-2] = 0;
  471.  
  472.     if ((dent = lookup (w, strlen (w))) != NULL) {
  473.         if (dent->v_flag)
  474.             wordok = 1;
  475.         return;
  476.     }
  477.  
  478.     if (p[-4] == 'E')
  479.         return;
  480.  
  481.     p[-3] = 0;
  482.  
  483.     if ((dent = lookup (w, strlen (w))) != NULL && dent->v_flag)
  484.         wordok = 1;
  485.     return;
  486. }
  487.  
  488. /* flags: y */
  489. y_ending (w)
  490. char *w;
  491. {
  492.     char *p;
  493.     struct dent *dent;
  494.  
  495.     p = w + strlen (w);
  496.  
  497.     if (strcmp (p-2, "LY") != 0)
  498.         return;
  499.  
  500.     p[-2] = 0;
  501.  
  502.     if ((dent = lookup (w, strlen (w))) != NULL && dent->y_flag)
  503.         wordok = 1;
  504.     return;
  505. }
  506.  
  507. vowel (c)
  508. char c;
  509. {
  510.     return (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
  511. }
  512.